#ifndef _RICHTEXTSYMBOLDLG_H_
#define _RICHTEXTSYMBOLDLG_H_

#include "wx/dialog.h"
#include "wx/vscroll.h"

class wxStaticText;
class wxComboBox;
class wxTextCtrl;
class wxSymbolListCtrl;

#ifndef __UNICODE__
#define __UNICODE__
#endif

#define SYMBOL_WXSYMBOLPICKERDIALOG_STYLE (wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxCLOSE_BOX)
#define SYMBOL_WXSYMBOLPICKERDIALOG_TITLE wxGetTranslation(wxT("Symbols"))
#define SYMBOL_WXSYMBOLPICKERDIALOG_IDNAME ID_SYMBOLPICKERDIALOG
#define SYMBOL_WXSYMBOLPICKERDIALOG_SIZE wxSize(400, 300)
#define SYMBOL_WXSYMBOLPICKERDIALOG_POSITION wxDefaultPosition

class wxSymbolPickerDialog: public wxDialog {
    DECLARE_DYNAMIC_CLASS( wxSymbolPickerDialog )
    DECLARE_EVENT_TABLE()

  public:
    wxSymbolPickerDialog();
    wxSymbolPickerDialog( const wxString& symbol, const wxString& fontName, const wxString& normalTextFont,
                          wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = SYMBOL_WXSYMBOLPICKERDIALOG_TITLE, const wxPoint& pos = SYMBOL_WXSYMBOLPICKERDIALOG_POSITION, const wxSize& size = SYMBOL_WXSYMBOLPICKERDIALOG_SIZE, long style = SYMBOL_WXSYMBOLPICKERDIALOG_STYLE );

    bool Create( const wxString& symbol, const wxString& fontName, const wxString& normalTextFont,
                 wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& caption = SYMBOL_WXSYMBOLPICKERDIALOG_TITLE, const wxPoint& pos = SYMBOL_WXSYMBOLPICKERDIALOG_POSITION, const wxSize& size = SYMBOL_WXSYMBOLPICKERDIALOG_SIZE, long style = SYMBOL_WXSYMBOLPICKERDIALOG_STYLE );
    void Init();
    void CreateControls();
    void UpdateSymbolDisplay( bool updateSymbolList = true, bool showAtSubset = true );
    void OnSymbolSelected( wxCommandEvent& event );
    void SetUnicodeMode( bool unicodeMode );
    void ShowAtSubset();
    int GetSymbolChar() const;
    bool HasSelection() const { return !m_symbol.IsEmpty(); }
    bool UseNormalFont() const { return m_fontName.IsEmpty(); }
    static bool ShowToolTips() { return sm_showToolTips; }
    static void SetShowToolTips( bool show ) { sm_showToolTips = show; }
    virtual bool TransferDataToWindow();
    void OnFontCtrlSelected( wxCommandEvent& event );
    void OnSubsetSelected( wxCommandEvent& event );
    void OnFromUnicodeSelected( wxCommandEvent& event );

    #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXPM__) || defined(__WXMGL__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || defined(__WXX11__) || defined(__WXPALMOS__)
    void OnOkUpdate( wxUpdateUIEvent& event );

    #endif
    wxString GetFontName() const { return m_fontName ; }
    void SetFontName( wxString value ) { m_fontName = value ; }
    wxString GetSymbol() const { return m_symbol ; }
    void SetSymbol( wxString value ) { m_symbol = value ; }
    bool GetFromUnicode() const { return m_fromUnicode ; }
    void SetFromUnicode( bool value ) { m_fromUnicode = value ; }
    wxString GetNormalTextFontName() const { return m_normalTextFontName ; }
    void SetNormalTextFontName( wxString value ) { m_normalTextFontName = value ; }
    wxBitmap GetBitmapResource( const wxString& name );
    wxIcon GetIconResource( const wxString& name );
    wxComboBox* m_fontCtrl;
    wxComboBox* m_subsetCtrl;
    wxSymbolListCtrl* m_symbolsCtrl;
    wxStaticText* m_symbolStaticCtrl;
    wxTextCtrl* m_characterCodeCtrl;
    wxComboBox* m_fromUnicodeCtrl;
    wxString m_fontName;
    wxString m_symbol;
    bool m_fromUnicode;
    wxString m_normalTextFontName;
    enum {
      ID_SYMBOLPICKERDIALOG = 10600,
      ID_SYMBOLPICKERDIALOG_FONT = 10602,
      ID_SYMBOLPICKERDIALOG_SUBSET = 10605,
      ID_SYMBOLPICKERDIALOG_LISTCTRL = 10608,
      ID_SYMBOLPICKERDIALOG_CHARACTERCODE = 10601,
      ID_SYMBOLPICKERDIALOG_FROM = 10603
    };
    bool m_dontUpdate;
    static bool sm_showToolTips;
};

class wxSymbolListCtrl : public wxVScrolledWindow {
  public:
    wxSymbolListCtrl() { Init(); }
    wxSymbolListCtrl( wxWindow *parent,
                      wxWindowID id = wxID_ANY,
                      const wxPoint& pos = wxDefaultPosition,
                      const wxSize& size = wxDefaultSize,
                      long style = 0,
                      const wxString& name = wxPanelNameStr ) {
      Init();
      ( void )Create( parent, id, pos, size, style, name );
    }
    bool Create( wxWindow *parent,
                 wxWindowID id = wxID_ANY,
                 const wxPoint& pos = wxDefaultPosition,
                 const wxSize& size = wxDefaultSize,
                 long style = 0,
                 const wxString& name = wxPanelNameStr );

    virtual ~wxSymbolListCtrl();
    virtual bool SetFont( const wxFont& font );
    void SetUnicodeMode( bool unicodeMode );
    int GetSelection() const;
    bool IsSelected( int item ) const;
    bool IsCurrentItem( int item ) const { return item == m_current; }
    wxPoint GetMargins() const { return m_ptMargins; }
    const wxColour& GetSelectionBackground() const { return m_colBgSel; }
    void SetSelection( int selection );
    void EnsureVisible( int item );
    void SetMargins( const wxPoint& pt );
    void SetMargins( wxCoord x, wxCoord y ) { SetMargins( wxPoint( x, y ) ); }
    void SetCellSize( const wxSize& sz ) { m_cellSize = sz; }
    const wxSize& GetCellSize() const { return m_cellSize; }
    void SetSelectionBackground( const wxColour& col );
    virtual wxVisualAttributes GetDefaultAttributes() const {
      return GetClassDefaultAttributes( GetWindowVariant() );
    }
    static wxVisualAttributes
    GetClassDefaultAttributes( wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL );
    int GetMinSymbolValue() const { return m_minSymbolValue; }
    int GetMaxSymbolValue() const { return m_maxSymbolValue; }
    void OnSize( wxSizeEvent& event );
  protected:
    virtual void OnDrawItem( wxDC& dc, const wxRect& rect, size_t n ) const;
    virtual wxCoord OnGetLineHeight( size_t line ) const;
    void OnPaint( wxPaintEvent& event );
    void OnKeyDown( wxKeyEvent& event );
    void OnLeftDown( wxMouseEvent& event );
    void OnLeftDClick( wxMouseEvent& event );
    void Init();
    void SendSelectedEvent();
    bool DoSetCurrent( int current );
    enum {
      ItemClick_Shift = 1,
      ItemClick_Ctrl  = 2,
      ItemClick_Kbd   = 4
    };
    void DoHandleItemClick( int item, int flags );
    int SymbolValueToLineNumber( int item );
    void SetupCtrl( bool scrollToSelection = true );
    int HitTest( const wxPoint& pt );
  private:
    int m_current;
    wxPoint     m_ptMargins;
    wxColour    m_colBgSel;
    wxBitmap*   m_doubleBuffer;
    wxSize      m_cellSize;
    int         m_minSymbolValue;
    int         m_maxSymbolValue;
    int         m_symbolsPerLine;
    bool        m_unicodeMode;
    DECLARE_EVENT_TABLE()
    DECLARE_NO_COPY_CLASS( wxSymbolListCtrl )
    DECLARE_ABSTRACT_CLASS( wxSymbolListCtrl )
};

#endif
